package com.didd.core.mybatis.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.didd.core.common.base.SimplePage;
import com.didd.core.common.utils.BeanUtil;
import com.didd.core.exception.BizException;
import com.didd.core.mybatis.query.DidddQueryChainWrapper;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.List;

/**
 * 封裝 mybatis-plus  ServiceImpl
 *
 * @author diddd
 * @Created 2020/11/4 14:51
 */
@Slf4j
public abstract class MybatisServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> {

    /**
     * 查询单条
     *
     * @param filter      查询条件
     * @param warnMessage 自定义异常信息
     * @param isThrowable 是否抛出异常
     * @return
     */
    public T filterOne(T filter, String warnMessage, Boolean isThrowable) {
        List<T> list = this.list(new QueryWrapper<>(filter));
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        if (isThrowable) {
            log.error("查询数据不存在:filter:[{}]", filter.toString());
            throw new BizException(warnMessage);
        }
        return null;
    }

    /**
     * 根据主键查询数据
     *
     * @param id
     * @param warnMessage
     * @param isThrowable
     * @return
     */
    public T findByPk(Serializable id, String warnMessage, Boolean isThrowable) {
        T entity = this.getById(id);
        if (entity != null) {
            return entity;
        }
        if (isThrowable) {
            log.error("数据不存在:id:[{}]", id);
            throw new BizException(warnMessage);
        }
        return null;
    }

    /**
     * @param pageNo      分页参数 页码
     * @param pageSize    分页参数 每页记录数
     * @param filter      查询条件
     * @param resultClass 返回对象实例类型 需继承数据库实体
     * @return
     */
    public SimplePage<T> queryPage(Integer pageNo, Integer pageSize, T filter) {
        IPage<T> pageHelper = new Page<>(pageNo, pageSize);
        pageHelper = this.page(pageHelper, new QueryWrapper<>(filter));
        return new SimplePage<>(pageHelper.getTotal(), pageHelper.getRecords());
    }

    /**
     * @param pageNo      分页参数 页码
     * @param pageSize    分页参数 每页记录数
     * @param filter      查询条件
     * @param resultClass 返回对象实例类型
     * @return
     */
    public SimplePage<?> queryPage(Integer pageNo, Integer pageSize, T filter, Class<?> resultClass) {
        IPage<T> pageHelper = new Page<>(pageNo, pageSize);
        pageHelper = this.page(pageHelper, new QueryWrapper<>(filter));
        return SimplePage.builder(resultClass).page(pageHelper).build();
    }

    /**
     * 查询 列表
     *
     * @param filter 查询条件
     * @return
     */
    public List<?> queryList(T filter, Class<?> resultClass) {
        return BeanUtil.copyList(this.queryList(filter), resultClass);
    }

    /**
     * 查询 列表
     *
     * @param filter 查询条件
     * @return
     */
    public List<T> queryList(T filter) {
        return this.list(new QueryWrapper<>(filter));
    }

    /**
     * 条件查询构造器
     *
     * @return
     */
    public DidddQueryChainWrapper<T> withQuery() {
        return new DidddQueryChainWrapper<>(this.getBaseMapper());
    }

}
